/**
 * @Project: SanxiapayCommon
 * @Title: SignUtil.java
 * @Package com.hundsun.epay.pay
 * @Description: TODO(用一句话描述该文件做什么)
 * @author Administrator yedm@hundsun.com
 * @date 2014-9-29 下午02:24:57
 * @Copyright: 2014 www.hundsun.com All Rights Reserved.
 * @version V1.0.0.0
 */
package com.hundsun.epay.pay.privatekey;

import goja.GojaConfig;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @author jinxn jinxn@hundsun.com
 * @ClassName SignUtil
 * @Description 签名工具类
 * @date 2014-9-29
 */
@SuppressWarnings("JavaDoc")
public class SignUtil {
    /** ==========MD5加密==========**/
    /**
     * @param key    私钥
     * @param params 参数 （输入参数案例： a=a1&b=b1）
     * @return
     * @throws Exception
     * @Method: encrypt
     * @Description: 签名（通过字符串的形式）
     */
    public static String encryptMD5(String key, String params) throws Exception {
        //1.将params中的参数进行重新排序
        params = modifyParams(params);
        //2.将key拼接到url后面
        String temp = params + "&" + key;
        //3.加密
        return MD5Util.getEncryptedPwd(temp);
    }

    /**
     * @param key    私钥
     * @param params 参数
     * @return
     * @throws Exception
     * @Method: encrypt
     * @Description:签名
     */
    public static String encryptMD5(String key, Map<String, String> params) throws Exception {
        //1.将params中的参数进行重新排序
        String para = modifyParams(params);
        //2.将key拼接到url后面
        String temp = para + "&" + key;
        //3.加密
        return MD5Util.getEncryptedPwd(temp);
    }

    /**
     * @param params 参数
     * @return
     * @Method: encrypt
     * @Description: 客户端签名
     */
    public static String clientEncryptMD5(Map<String, String> params) throws Exception {
        String key = getPropertiesKey();
        return encryptMD5(key, params);
    }

    /**
     * @param key    私钥
     * @param params
     * @return
     * @Method: encrypt
     * @Description: 客户端获取完整签名报文
     */
    public static String clientGetSignMessageMD5(String key, Map<String, String> params) throws Exception {
        //排序参数
        String para = modifyParams(params);
        String temp = para + "&" + key;
        //加密
        String sign = MD5Util.getEncryptedPwd(temp);
        return para + "&signType=MD5&sign=" + sign;
    }

    /**
     * @param params 参数
     * @return
     * @Method: encrypt
     * @Description: 客户端获取完整签名报文
     */
    public static String clientGetSignMessageMD5(Map<String, String> params) throws Exception {
        String key = getPropertiesKey();
        //排序参数
        String para = modifyParams(params);
        String temp = para + "&" + key;
        //加密
        String sign = MD5Util.getEncryptedPwd(temp);
        return para + "&signType=MD5&md5Sign=" + sign;
    }
    /** ==========MD5加密==========**/
    /**
     * @param params
     * @return
     * @throws Exception
     * @Method: modifyParams
     * @Description: 参数重新排序
     */
    private static String modifyParams(String params) throws Exception {
        String result = "";
        String[] arrayParam = params.split("&");
        Map<String, String> map = new HashMap<String, String>();
        //获取所有键值对
        for (int i = 0; i < arrayParam.length; i++) {
            String param = arrayParam[i];
            if ("".equals(param)) {
                continue;
            }
            //获取第一个'='的位置
            int index = param.indexOf("=", 0);
            String key = "";
            String value = "";
            if (index == -1) {
                key = param.substring(0);
            } else {
                key = param.substring(0, index);
                value = param.substring(index + 1);
            }
            map.put(key, value);
        }
        //按照键来进行排序
        String[] args = new String[map.size()];
        Set<String> keys = map.keySet();
        Iterator<String> iterator = keys.iterator();
        int i = 0;
        while (iterator.hasNext()) {
            args[i] = iterator.next();
            i++;
        }
        Arrays.sort(args);
        //重组url
        for (int j = 0; j < args.length; j++) {
            String key = args[j];
            String value = map.get(key);
            result += "&" + key + "=" + value;
        }
        if (result.length() > 0) {
            result = result.substring(1);
        }
        return result;
    }

    /**
     * @param params
     * @return
     * @throws Exception
     * @Method: modifyParams
     * @Description: 参数重新排序
     */
    private static String modifyParams(Map<String, String> params) throws Exception {
        String result = "";
        String[] args = new String[params.size()];
        Set<String> keys = params.keySet();
        Iterator<String> iterator = keys.iterator();
        int i = 0;
        while (iterator.hasNext()) {
            args[i] = iterator.next();
            i++;
        }
        Arrays.sort(args);
        //重组url
        for (int j = 0; j < args.length; j++) {
            String key = args[j];
            String value = params.get(key);
            result += "&" + key + "=" + value;
        }
        if (result.length() > 0) {
            result = result.substring(1);
        }
        return result;
    }

    /**
     * @return
     * @Method: getKey
     * @Description: 获取私钥
     */
    private static String getPropertiesKey() {
        return GojaConfig.getProperty("bank.merchant.personalKey");
    }

}
